package algorithm;

import java.math.BigDecimal;

//使用AHP层次分析法确定权值,输入一个double类型二位数组（各个因素的相对重要比例），输出一个double类型一位数组（各个因素的权值），
public class Dynamic_weight {
	// 平均随机一致性指针  
    public double[] RI = { 0.00, 0.00, 0.58, 0.90, 1.12, 1.21, 1.32, 1.41, 1.45, 1.49 };   
    // 随机一致性比率  
    public double CR = 0.0;  
    // 最大特征值  
    public double lamta = 0.0;
    
    
	public double[] Get_weight(double[][] a) {  
		int N = a[0].length;
		int flag = 1;//数据有效性标志，0数据无效，1数据有效
		for(int i = 0;i < N;i++){   //数据的正确性检验
			for(int j = 0;j < N;j++){
				if(a[i][j] * a[j][i] != 1 ){
					flag = 0;
				}
			}
		}
        // 初始向量Wk  
        double[] w0 = new double[N];
        double weight[] = new double[N];
        for (int i = 0; i < N; i++) {  
            w0[i] = 1.0 / N;  
        }  
  
        // 一般向量W（k+1）  
        double[] w1 = new double[N];  
  
        // W（k+1）的归一化向量  
        double[] w2 = new double[N];  
  
        double sum = 1.0;  
  
        double d = 1.0;  
  
        // 误差  
        double delt = 0.00001;  
  
        while (d > delt) {  
            d = 0.0;  
            sum = 0;  
  
            // 获取向量  
            for (int j = 0; j < N; j++) {  
                double t = 0.0;  
                for (int l = 0; l < N; l++)  
                    t += a[j][l] * w0[l];  
                // w1[j] = a[j][0] * w0[0] + a[j][1] * w0[1] + a[j][2] * w0[2];  
                w1[j] = t;  
                sum += w1[j];  
            }  
  
            // 向量归一化  
            for (int k = 0; k < N; k++) {  
                w2[k] = w1[k] / sum;  
  
                // 最大差值  
                d = Math.max(Math.abs(w2[k] - w0[k]), d);  
  
                // 用于下次迭代使用  
                w0[k] = w2[k];  
            }  
        }  
  
        // 计算矩阵最大特征值lamta，CI，RI  
        lamta = 0.0;  
  
        for (int k = 0; k < N; k++) {  
            lamta += w1[k] / (N * w0[k]);  
        }  
  
        double CI = (lamta - N) / (N - 1);  
  
        if (RI[N - 1] != 0) {  
            CR = CI / RI[N - 1];  
        }  
  
        // 四舍五入处理  
        lamta = round(lamta, 3);  
        CI = round(CI, 3);  
        CR = round(CR, 3);  
        
        if(CR < 0.1){
        	for (int i = 0; i < N; i++) {  
        		w0[i] = round(w0[i], 4);  
        		w1[i] = round(w1[i], 4);  
        		w2[i] = round(w2[i], 4); 
        		weight[i] = w2[i];  
        	}  
        }
        else{
        	flag = 0;
        }  
        return weight;
    }  
	
	  private double round(double v, int scale) {  
	        if (scale < 0) {  
	            throw new IllegalArgumentException(  
	                    "The scale must be a positive integer or zero");  
	        }  
	        BigDecimal b = new BigDecimal(Double.toString(v));  
	        BigDecimal one = new BigDecimal("1");  
	        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();  
	    }  
}
